Reorganize gdk_pixbuf_loader_write into three functions, and eliminate
authorElliot Lee <sopwith@src.gnome.org>
Tue, 2 Nov 1999 16:10:25 +0000 (16:10 +0000)
committerElliot Lee <sopwith@src.gnome.org>
Tue, 2 Nov 1999 16:10:25 +0000 (16:10 +0000)
* src/gdk-pixbuf-loader.c: Reorganize gdk_pixbuf_loader_write into three functions, and eliminate
duplication of code from write() and close(). Also fix bug where the 128-byte header was being
written twice.

gdk-pixbuf/ChangeLog
gdk-pixbuf/gdk-pixbuf-loader.c
gdk-pixbuf/io-jpeg.c
gtk/gdk-pixbuf-loader.c

index 487993ecba0b1b62bea97cff1dc254ae91448b6a..5dc73a1731b025fe378446af7981e7d7eca77620 100644 (file)
@@ -1,5 +1,10 @@
-1999-11-01  Federico Mena Quintero  <federico@redhat.com>
+1999-11-02 Elliot Lee <sopwith@redhat.com>
+       * src/gdk-pixbuf-loader.c: Reorganize gdk_pixbuf_loader_write into
+       three functions, and eliminate duplication of code from write()
+       and close(). Also fix bug where the 128-byte header was being
+       written twice.
 
+1999-11-01  Federico Mena Quintero  <federico@redhat.com>
        * src/gnome-canvas-pixbuf.c (recompute_bounding_box): Fixed
        bounding box computation.
 
index ddb4ad3eec34e3ccc8ca53917a8bb41e3e72b8ff..160d139840cbc9a2b739f5220945f6eb8276e0da 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
 /* GdkPixbuf library - Main header file
  *
  * Copyright (C) 1999 The Free Software Foundation
@@ -48,11 +50,14 @@ static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 };
 \f
 
 /* Internal data */
+
+#define LOADER_HEADER_SIZE 128
+
 typedef struct {
        GdkPixbuf *pixbuf;
        gboolean closed;
-       gchar buf[128];
-       gint buf_offset;
+       gchar header_buf[LOADER_HEADER_SIZE];
+       gint header_buf_offset;
        GdkPixbufModule *image_module;
        gpointer context;
 } GdkPixbufLoaderPrivate;
@@ -230,6 +235,60 @@ gdk_pixbuf_loader_new (void)
        return gtk_type_new (gdk_pixbuf_loader_get_type ());
 }
 
+static int
+gdk_pixbuf_loader_load_module(GdkPixbufLoader *loader)
+{
+       GdkPixbufLoaderPrivate *priv = loader->private;
+
+       priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset);
+
+       if (priv->image_module == NULL)
+               return 0;
+
+       if (priv->image_module->module == NULL)
+               gdk_pixbuf_load_module (priv->image_module);
+
+       if (priv->image_module->module == NULL)
+               return 0;
+
+       if ((priv->image_module->begin_load == NULL) ||
+           (priv->image_module->stop_load == NULL) ||
+           (priv->image_module->load_increment == NULL)) {
+               g_warning ("module %s does not support incremental loading.\n",
+                          priv->image_module->module_name);
+               return 0;
+       }
+
+       priv->context = (*priv->image_module->begin_load) (gdk_pixbuf_loader_prepare, loader);
+
+       if (priv->context == NULL) {
+               g_warning("Failed to begin progressive load");
+               return 0;
+       }
+
+       if( (* priv->image_module->load_increment) (priv->context, priv->header_buf, priv->header_buf_offset) )
+               return priv->header_buf_offset;
+       return 0;
+}
+
+static int
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
+{
+       int nbytes;
+       GdkPixbufLoaderPrivate *priv = loader->private;
+
+       nbytes = MIN(LOADER_HEADER_SIZE - priv->header_buf_offset, count);
+       memcpy (priv->header_buf + priv->header_buf_offset, buf, nbytes);
+           
+       priv->header_buf_offset += nbytes;
+           
+       if(priv->header_buf_offset >= LOADER_HEADER_SIZE) {
+               return gdk_pixbuf_loader_load_module(loader);
+       } else
+               return nbytes;
+}
+
 /**
  * gdk_pixbuf_loader_write:
  * @loader: A pixbuf loader.
@@ -250,6 +309,7 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
 
        g_return_val_if_fail (loader != NULL, FALSE);
        g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE);
+
        g_return_val_if_fail (buf != NULL, FALSE);
        g_return_val_if_fail (count >= 0, FALSE);
 
@@ -259,56 +319,17 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
        g_return_val_if_fail (priv->closed == FALSE, FALSE);
 
        if (priv->image_module == NULL) {
-               gboolean retval = TRUE;
-
-               memcpy (priv->buf + priv->buf_offset,
-                       buf,
-                       (priv->buf_offset + count > 128) ? (128 - priv->buf_offset) : count);
-
-               if (priv->buf_offset + count >= 128) {
-                       /* We have enough data to start doing something with the image */
-                       priv->image_module = gdk_pixbuf_get_module (priv->buf, 128);
-                       if (priv->image_module == NULL)
-                               return FALSE;
-                       else if (priv->image_module->module == NULL)
-                               gdk_pixbuf_load_module (priv->image_module);
-
-                       if ((priv->image_module->begin_load == NULL) ||
-                           (priv->image_module->stop_load == NULL) ||
-                           (priv->image_module->load_increment == NULL)) {
-                               g_warning ("module %s does not support incremental loading.\n",
-                                          priv->image_module->module_name);
-                               return FALSE;
-                       } else {
-                               priv->context = (*priv->image_module->begin_load) (
-                                       gdk_pixbuf_loader_prepare, loader);
-                               
-                                if (priv->context == NULL) {
-                                        g_warning("Failed to begin progressive load");
-                                        return FALSE;
-                                }
-                                
-                               retval = (* priv->image_module->load_increment) (
-                                       priv->context, priv->buf, 128);
-
-                               /* if we had more then 128 bytes total, we want
-                                * to send the rest of the buffer.
-                                */
-
-                               if (retval && (priv->buf_offset + count) > 128) {
-                                       retval = (* priv->image_module->load_increment) (
-                                               priv->context,
-                                               buf,
-                                               count + priv->buf_offset - 128);
-                               }
-                       }
-               } else
-                       priv->buf_offset += count;
-
-               return retval;
+               int eaten;
+
+               eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count);
+               if (eaten <= 0)
+                       return FALSE;
+
+               count -= eaten;
+               buf += eaten;
        }
 
-       if (priv->image_module->load_increment)
+       if (count > 0 && priv->image_module->load_increment)
                return (* priv->image_module->load_increment) (priv->context, buf, count);
 
        return (FALSE);
@@ -360,22 +381,8 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader)
        g_return_if_fail (priv->closed == FALSE);
 
        /* We have less the 128 bytes in the image.  Flush it, and keep going. */
-       if (priv->image_module == NULL) {
-               priv->image_module = gdk_pixbuf_get_module (priv->buf, priv->buf_offset);
-               if (priv->image_module &&
-                   ((priv->image_module->begin_load == NULL) ||
-                    (priv->image_module->stop_load == NULL) ||
-                    (priv->image_module->load_increment == NULL))) {
-                       g_warning ("module %s does not support incremental loading.\n",
-                                  priv->image_module->module_name);
-               } else if (priv->image_module) {
-                       g_print ("module loaded: name is %s\n", priv->image_module->module_name);
-                       priv->context = (* priv->image_module->begin_load) (
-                               gdk_pixbuf_loader_prepare, loader);
-                       (* priv->image_module->load_increment) (priv->context,
-                                                               priv->buf, priv->buf_offset);
-               }
-       }
+       if (priv->image_module == NULL)
+               gdk_pixbuf_loader_load_module (loader);
 
        if (priv->image_module && priv->image_module->stop_load)
                (* priv->image_module->stop_load) (priv->context);
index 82954d61341b4d04ef48fa6f3af3ffe2b910906b..89ab14ca2d20dcbb8e7858952105c834931125cc 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <config.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <setjmp.h>
 #include <jpeglib.h>
 #include "gdk-pixbuf.h"
 \f
 
 /* we are a "source manager" as far as libjpeg is concerned */
+#define JPEG_PROG_BUF_SIZE 4096
+
 typedef struct {
        struct jpeg_source_mgr pub;   /* public fields */
 
-       JOCTET * buffer;              /* start of buffer */
-       gboolean start_of_file;       /* have we gotten any data yet? */
+       JOCTET buffer[JPEG_PROG_BUF_SIZE];              /* start of buffer */
        long  skip_next;              /* number of bytes to skip next read */
-       
+
 } my_source_mgr;
 
 typedef my_source_mgr * my_src_ptr;
@@ -85,8 +88,6 @@ typedef struct {
        struct error_handler_data     jerr;
 } JpegProgContext;
 
-#define JPEG_PROG_BUF_SIZE 4096
-
 GdkPixbuf *image_load (FILE *f);
 gpointer image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data);
 void image_stop_load (gpointer context);
@@ -227,7 +228,6 @@ init_source (j_decompress_ptr cinfo)
 {
        my_src_ptr src = (my_src_ptr) cinfo->src;
 
-       src->start_of_file = TRUE;
        src->skip_next = 0;
 }
 
@@ -278,7 +278,7 @@ image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data)
        JpegProgContext *context;
        my_source_mgr   *src;
 
-       context = g_new (JpegProgContext, 1);
+       context = g_new0 (JpegProgContext, 1);
        context->notify_func = func;
        context->notify_user_data = user_data;
        context->pixbuf = NULL;
@@ -289,9 +289,8 @@ image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data)
        /* create libjpeg structures */
        jpeg_create_decompress (&context->cinfo);
 
-       context->cinfo.src = (struct jpeg_source_mgr *) g_new (my_source_mgr, 1);
+       context->cinfo.src = (struct jpeg_source_mgr *) g_new0 (my_source_mgr, 1);
        src = (my_src_ptr) context->cinfo.src;
-       src->buffer = g_malloc (JPEG_PROG_BUF_SIZE);
 
        context->cinfo.err = jpeg_std_error (&context->jerr.pub);
 
@@ -316,6 +315,7 @@ void
 image_stop_load (gpointer data)
 {
        JpegProgContext *context = (JpegProgContext *) data;
+
        g_return_if_fail (context != NULL);
 
        if (context->pixbuf)
@@ -324,8 +324,6 @@ image_stop_load (gpointer data)
        if (context->cinfo.src) {
                my_src_ptr src = (my_src_ptr) context->cinfo.src;
                
-               if (src->buffer)
-                       g_free (src->buffer);
                g_free (src);
        }
 
@@ -352,12 +350,12 @@ image_load_increment (gpointer data, guchar *buf, guint size)
        struct jpeg_decompress_struct *cinfo;
        my_src_ptr  src;
        guint       num_left, num_copy;
-       guchar      *nextptr;
 
        g_return_val_if_fail (context != NULL, FALSE);
        g_return_val_if_fail (buf != NULL, FALSE);
 
        src = (my_src_ptr) context->cinfo.src;
+
        cinfo = &context->cinfo;
 
        /* skip over data if requested, handle unsigned int sizes cleanly */
@@ -376,22 +374,26 @@ image_load_increment (gpointer data, guchar *buf, guint size)
 
        while (num_left > 0) {
                /* copy as much data into buffer as possible */
-               num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
-                               size);
 
-               if (num_copy == 0) 
-                       g_assert ("Buffer overflow!\n");
+               if(src->pub.bytes_in_buffer)
+                 {
+                   int space_used =
+                     JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer;
 
-               nextptr = src->buffer + src->pub.bytes_in_buffer;
-               memcpy (nextptr, buf, num_copy);
-               
-               if (src->pub.next_input_byte == NULL ||
-                   src->pub.bytes_in_buffer == 0)
-                       src->pub.next_input_byte = src->buffer;
+                   memmove(src->buffer, src->buffer + space_used, src->pub.bytes_in_buffer);
+                   g_print("Moving %d bytes from offset %d to head\n", src->pub.bytes_in_buffer, space_used);
+                 }
 
+               num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
+                               size);
+               if (num_copy == 0) 
+                 g_error ("Buffer overflow!");
+               memcpy(src->buffer + src->pub.bytes_in_buffer, buf, num_copy);
+               src->pub.next_input_byte = src->buffer;
                src->pub.bytes_in_buffer += num_copy;
-
                num_left -= num_copy;
+               g_print("Copied %d bytes, now have %d in buffer, %d left\n", num_copy, src->pub.bytes_in_buffer, num_left);
+               G_BREAKPOINT();
 
                /* try to load jpeg header */
                if (!context->got_header) {
@@ -399,6 +401,7 @@ image_load_increment (gpointer data, guchar *buf, guint size)
 
                        rc = jpeg_read_header (cinfo, TRUE);
                        context->src_initialized = TRUE;
+
                        if (rc == JPEG_SUSPENDED)
                                continue;
 
@@ -418,7 +421,7 @@ image_load_increment (gpointer data, guchar *buf, guint size)
 
                        if (context->pixbuf == NULL) {
                                /* Failed to allocate memory */
-                               g_assert ("Couldn't allocate gdkpixbuf\n");
+                               g_error ("Couldn't allocate gdkpixbuf");
                        }
 
                        /* Use pixbuf buffer to store decompressed data */
@@ -430,7 +433,6 @@ image_load_increment (gpointer data, guchar *buf, guint size)
                                (* context->notify_func) (context->pixbuf,
                                                          context->notify_user_data);
 
-                       src->start_of_file = FALSE;
                } else if (!context->did_prescan) {
                        int rc;
 
index ddb4ad3eec34e3ccc8ca53917a8bb41e3e72b8ff..160d139840cbc9a2b739f5220945f6eb8276e0da 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
 /* GdkPixbuf library - Main header file
  *
  * Copyright (C) 1999 The Free Software Foundation
@@ -48,11 +50,14 @@ static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 };
 \f
 
 /* Internal data */
+
+#define LOADER_HEADER_SIZE 128
+
 typedef struct {
        GdkPixbuf *pixbuf;
        gboolean closed;
-       gchar buf[128];
-       gint buf_offset;
+       gchar header_buf[LOADER_HEADER_SIZE];
+       gint header_buf_offset;
        GdkPixbufModule *image_module;
        gpointer context;
 } GdkPixbufLoaderPrivate;
@@ -230,6 +235,60 @@ gdk_pixbuf_loader_new (void)
        return gtk_type_new (gdk_pixbuf_loader_get_type ());
 }
 
+static int
+gdk_pixbuf_loader_load_module(GdkPixbufLoader *loader)
+{
+       GdkPixbufLoaderPrivate *priv = loader->private;
+
+       priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset);
+
+       if (priv->image_module == NULL)
+               return 0;
+
+       if (priv->image_module->module == NULL)
+               gdk_pixbuf_load_module (priv->image_module);
+
+       if (priv->image_module->module == NULL)
+               return 0;
+
+       if ((priv->image_module->begin_load == NULL) ||
+           (priv->image_module->stop_load == NULL) ||
+           (priv->image_module->load_increment == NULL)) {
+               g_warning ("module %s does not support incremental loading.\n",
+                          priv->image_module->module_name);
+               return 0;
+       }
+
+       priv->context = (*priv->image_module->begin_load) (gdk_pixbuf_loader_prepare, loader);
+
+       if (priv->context == NULL) {
+               g_warning("Failed to begin progressive load");
+               return 0;
+       }
+
+       if( (* priv->image_module->load_increment) (priv->context, priv->header_buf, priv->header_buf_offset) )
+               return priv->header_buf_offset;
+       return 0;
+}
+
+static int
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
+{
+       int nbytes;
+       GdkPixbufLoaderPrivate *priv = loader->private;
+
+       nbytes = MIN(LOADER_HEADER_SIZE - priv->header_buf_offset, count);
+       memcpy (priv->header_buf + priv->header_buf_offset, buf, nbytes);
+           
+       priv->header_buf_offset += nbytes;
+           
+       if(priv->header_buf_offset >= LOADER_HEADER_SIZE) {
+               return gdk_pixbuf_loader_load_module(loader);
+       } else
+               return nbytes;
+}
+
 /**
  * gdk_pixbuf_loader_write:
  * @loader: A pixbuf loader.
@@ -250,6 +309,7 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
 
        g_return_val_if_fail (loader != NULL, FALSE);
        g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE);
+
        g_return_val_if_fail (buf != NULL, FALSE);
        g_return_val_if_fail (count >= 0, FALSE);
 
@@ -259,56 +319,17 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
        g_return_val_if_fail (priv->closed == FALSE, FALSE);
 
        if (priv->image_module == NULL) {
-               gboolean retval = TRUE;
-
-               memcpy (priv->buf + priv->buf_offset,
-                       buf,
-                       (priv->buf_offset + count > 128) ? (128 - priv->buf_offset) : count);
-
-               if (priv->buf_offset + count >= 128) {
-                       /* We have enough data to start doing something with the image */
-                       priv->image_module = gdk_pixbuf_get_module (priv->buf, 128);
-                       if (priv->image_module == NULL)
-                               return FALSE;
-                       else if (priv->image_module->module == NULL)
-                               gdk_pixbuf_load_module (priv->image_module);
-
-                       if ((priv->image_module->begin_load == NULL) ||
-                           (priv->image_module->stop_load == NULL) ||
-                           (priv->image_module->load_increment == NULL)) {
-                               g_warning ("module %s does not support incremental loading.\n",
-                                          priv->image_module->module_name);
-                               return FALSE;
-                       } else {
-                               priv->context = (*priv->image_module->begin_load) (
-                                       gdk_pixbuf_loader_prepare, loader);
-                               
-                                if (priv->context == NULL) {
-                                        g_warning("Failed to begin progressive load");
-                                        return FALSE;
-                                }
-                                
-                               retval = (* priv->image_module->load_increment) (
-                                       priv->context, priv->buf, 128);
-
-                               /* if we had more then 128 bytes total, we want
-                                * to send the rest of the buffer.
-                                */
-
-                               if (retval && (priv->buf_offset + count) > 128) {
-                                       retval = (* priv->image_module->load_increment) (
-                                               priv->context,
-                                               buf,
-                                               count + priv->buf_offset - 128);
-                               }
-                       }
-               } else
-                       priv->buf_offset += count;
-
-               return retval;
+               int eaten;
+
+               eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count);
+               if (eaten <= 0)
+                       return FALSE;
+
+               count -= eaten;
+               buf += eaten;
        }
 
-       if (priv->image_module->load_increment)
+       if (count > 0 && priv->image_module->load_increment)
                return (* priv->image_module->load_increment) (priv->context, buf, count);
 
        return (FALSE);
@@ -360,22 +381,8 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader)
        g_return_if_fail (priv->closed == FALSE);
 
        /* We have less the 128 bytes in the image.  Flush it, and keep going. */
-       if (priv->image_module == NULL) {
-               priv->image_module = gdk_pixbuf_get_module (priv->buf, priv->buf_offset);
-               if (priv->image_module &&
-                   ((priv->image_module->begin_load == NULL) ||
-                    (priv->image_module->stop_load == NULL) ||
-                    (priv->image_module->load_increment == NULL))) {
-                       g_warning ("module %s does not support incremental loading.\n",
-                                  priv->image_module->module_name);
-               } else if (priv->image_module) {
-                       g_print ("module loaded: name is %s\n", priv->image_module->module_name);
-                       priv->context = (* priv->image_module->begin_load) (
-                               gdk_pixbuf_loader_prepare, loader);
-                       (* priv->image_module->load_increment) (priv->context,
-                                                               priv->buf, priv->buf_offset);
-               }
-       }
+       if (priv->image_module == NULL)
+               gdk_pixbuf_loader_load_module (loader);
 
        if (priv->image_module && priv->image_module->stop_load)
                (* priv->image_module->stop_load) (priv->context);